import java.util.*;

//  Map 和 Set

//Map
// 1. Map是一个接口，不能直接实例化对象，如果要实例化对象只能实例化其实现类TreeMap或者HashMap
// 2. Map中存放键值对的Key是唯一的，value是可以重复的
// 3. 在Map中插入键值对时，key不能为空，否则就会抛NullPointerException异常，但是value可以为空 （Hashmap是可以的）
// 4. Map中的Key可以全部分离出来，存储到Set中来进行访问(因为Key不能重复)。
// 5. Map中的value可以全部分离出来，存储在Collection的任何一个子集合中(value可能有重复)。
// 6. Map中键值对的Key不能直接修改，value可以修改，如果要修改key，只能先将该key删除掉，然后再来进行重新插入。
// 7. TreeMap和HashMap的区别

//Set 集合 存入里面的数据会自动去重
// 1. Set是继承自Collection的一个接口类
// 2. Set中只存储了key，并且要求key一定要唯一
// 3. Set的底层是使用Map来实现的，其使用key与Object的一个默认对象作为键值对插入到Map中的
// 4. Set最大的功能就是对集合中的元素进行去重
// 5. 实现Set接口的常用类有TreeSet和HashSet，还有一个LinkedHashSet，
// LinkedHashSet是在HashSet的基础上维护了一个双向链表来记录元素的插入次序。
// 6. Set中的Key不能修改，如果要修改，先将原来的删除掉，然后再重新插入
// 7. Set中不能插入null的key。
// 8. TreeSet和HashSet的区别
public class TestDemo {
    public static void main1(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("pig",1);
        map.put("dog",23);
        map.put("cat",12);
        System.out.println(map);//{cat=12, dog=23, pig=1}
//        为什么存放元素 打印出来顺序不一样
//        因为hashmap存储元素的时候 不是按照你的存储顺序进行打印的
//        存储的时候 是根据一个函数来进行存储的 具体存储到哪里 是由函数来确定的 这个函数就是哈希函数

//        获取val
        int ret = map.get("cat");//通过key 获取对应的val值
        System.out.println(ret);//12
//        int ret2 = map.get("cat2");error   NullPointerException
        System.out.println(map.get("duck"));//null
        System.out.println(map.getOrDefault("duck",98));//98

        Integer ret3 = map.remove("dog");
        System.out.println(ret3);//23
        System.out.println(map);//{cat=12, pig=1}
    }


    public static void main2(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("pig",1);
        map.put("dog",23);
        map.put("cat",12);
        map.put("cat",18);//key如果一样  val会被覆盖

        System.out.println(map);//{cat=18, dog=23, pig=1}
//        放回所有key的不重复集合
        Set<String> set = map.keySet();//Set这个集合当中存储的元素都是不重复的
        System.out.println(set);//[cat, dog, pig]

        map.put("duck",18);
        Collection<Integer> collection = map.values();//返回val的可重复集合
        System.out.println(collection);//[18, 18, 23, 1]
    }


    public static void main3(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put("pig",1);
        map.put("dog",23);
        map.put("cat",12);

//        返回所有的 key-value 映射关系
//        对于Set<>尖括号内   里面放Map.Entry<String,Integer>类型
        Set<Map.Entry<String,Integer>> entrySet = map.entrySet();
        System.out.println(entrySet);//[cat=12, dog=23, pig=1]
        for (Map.Entry<String,Integer> entry :entrySet) {
            System.out.println(entry.getKey()+ "->" +entry.getValue());
        }
        //cat->12
        //dog->23
        //pig->1
    }

    public static void main4(String[] args) {
        Map<String,Integer> map = new HashMap<>();
        map.put(null,null);

        Map<String,Integer> map2 = new TreeMap<>();
        map2.put(null,null);//运行报错 NullPointerException
    }


    public static void main5(String[] args) {
        Set<Integer> set = new HashSet<>();
        set.add(1);
        set.add(2);
        set.add(3);
        set.add(1);
        System.out.println(set);//[1, 2, 3]  自动去重
//        迭代器
        Iterator<Integer> iterator = set.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
        //1
        //2
        //3
    }
}
